#include <TGS/MapControl2.0/RendererList.h>
#include <TGS/GeoMath2.0/Envelope.h>
#include <algorithm>
#include <QString>

namespace TGS{
namespace MapControl{


RendererList::RendererList(void)
{
}


RendererList::~RendererList(void)
{
	std::for_each(_renderers.begin(), _renderers.end(),[&](Renderer* renderer)
	{
		if(renderer->manageMemoryByMapControl())
			delete renderer;
	});
	_renderers.clear();
}

void RendererList::render( RenderContext* renderContext )
{
	if(!isVisible()) return;

	std::for_each(_renderers.begin(), _renderers.end(),[&](Renderer* renderer)
	{
		if(renderer->isVisible())
			renderer->render(renderContext);
	});
}

void RendererList::addRenderer( Renderer* renderer )
{
	_renderers.push_back(renderer);
}


void RendererList::removeRenderer( Renderer* renderer )
{
	for (size_t i = 0; i < _renderers.size(); ++i)
	{
		if(renderer == _renderers[i])
		{
			if(renderer->manageMemoryByMapControl())
			{
				delete renderer;				
			}
			_renderers.erase(_renderers.begin() + i);
			--i;
			continue;
		}

		RendererList* rendererList = dynamic_cast<RendererList*>(_renderers[i]);
		if(rendererList)
		{
			removeRenderer(rendererList);
		}		
	}
}


const Renderer* RendererList::getRenderer( size_t index ) const
{
	return _renderers[index];
}

Renderer* RendererList::getRenderer( size_t index )
{
	return _renderers[index];
}

size_t RendererList::getRendererCount() const
{
	return _renderers.size();
}

Renderer* RendererList::findRendererRecursion( const QString& name )
{
	Renderer* result = nullptr;
	for (size_t i = 0; i < _renderers.size(); ++i)
	{
		if(name == _renderers[i]->getName())
		{
			return _renderers[i];
		}

		RendererList* rendererList = dynamic_cast<RendererList*>(_renderers[i]);
		if(rendererList)
		{
			result = rendererList->findRendererRecursion(name);
			if(nullptr != result)
			{
				return result;
			}
		}		
	}

	return result;
}

std::vector<Renderer*> RendererList::findRenderersRecursion( const QString& name )
{
	std::vector<Renderer*> result;
	for (size_t i = 0; i < _renderers.size(); ++i)
	{
		if(name == _renderers[i]->getName())
		{
			result.push_back(_renderers[i]);
		}

		RendererList* rendererList = dynamic_cast<RendererList*>(_renderers[i]);
		if(rendererList)
		{
			std::vector<Renderer*> temp = rendererList->findRenderersRecursion(name);
			result.insert(result.end(), temp.begin(), temp.end());
		}		
	}

	return result;
}

Renderer* RendererList::findRenderer( const QString& name )
{
	auto iter = std::find_if(_renderers.begin(), _renderers.end(), [&](Renderer* renderer)
	{
		return renderer->getName() == name;
	});

	return iter == _renderers.end() ? nullptr : *iter;
}

TGS::GeoMath::Envelope RendererList::getEnvelope() const
{
	if(!isVisible()) return Envelope();

	Envelope envelope;
	for (size_t i = 0; i < _renderers.size(); ++i)
	{
		if(! _renderers[i]->isVisible()) continue;
		Envelope temp = _renderers[i]->getEnvelope();
		if(!temp.isEmpty()) envelope.expandToInclude(temp);
	}

	return envelope;
}

void RendererList::clear()
{
	std::for_each(_renderers.begin(), _renderers.end(),[&](Renderer* renderer)
	{
		if(renderer->manageMemoryByMapControl())
		{
			delete renderer;
		}
	});

	_renderers.clear();
}

void RendererList::setSelectPolygon( const Polygon& selectPolygon )
{
	std::for_each(_renderers.begin(), _renderers.end(),[&](Renderer* renderer)
	{
		renderer->setSelectPolygon(selectPolygon);
	});
}

void RendererList::setSelectPoint( const Point& selectPoint )
{
	std::for_each(_renderers.begin(), _renderers.end(),[&](Renderer* renderer)
	{
		renderer->setSelectPoint(selectPoint);
	});
}

void RendererList::deselect()
{
	std::for_each(_renderers.begin(), _renderers.end(),[&](Renderer* renderer)
	{
		renderer->deselect();
	});
}

void RendererList::setDrawPolygon( const Polygon& drawedPolygon )
{
	std::for_each(_renderers.begin(), _renderers.end(),[&](Renderer* renderer)
	{
		renderer->setDrawPolygon(drawedPolygon);
	});
}



}//MapControl
}//TGS